﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Reflection;
using System.IO;
using System.Net;

namespace BSF.Tool
{
    
    /// <summary>
    /// XML操作
    /// </summary>
    public static class XmlHelper
    {
        public static XmlDocument xmlDoc = new XmlDocument();

        #region 读取指定路径配置文件值
        /// <summary>
        /// 读取指定路径配置文件值
        /// </summary>
        /// <param name="Target"></param>
        /// <param name="ConfigPathName"></param>
        /// <returns></returns>
        public static  string GetConfigValue(string Target, string XmlPath)
        {
            System.Xml.XmlDocument xdoc = new XmlDocument();
            xdoc.Load(XmlPath);
            XmlElement root = xdoc.DocumentElement;
            XmlNodeList elemList = root.GetElementsByTagName(Target);
            return elemList[0].InnerXml;
        }
        #endregion

        #region 获取XML指定的节点
        /// <summary>
        /// 获取XML指定的节点
        /// </summary>
        /// <param name="xmlPath">XML文件路径</param>
        /// <param name="nodePath">从根节点开始到要获取属性值的节点路径,如/Root/NodeName</param>
        /// <returns></returns>
        public static XmlNode GetXMLNode(this string xmlPath,string nodePath)
        {
            try
            {
                xmlDoc.Load(System.Web.HttpContext.Current.Server.MapPath(xmlPath));
                return xmlDoc.SelectSingleNode(nodePath);
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 获取XML指定的节点
        /// </summary>
        /// <param name="xmlPath">XML内容</param>
        /// <param name="nodePath">从根节点开始到要获取属性值的节点路径,如/Root/NodeName</param>
        /// <returns></returns>
        public static string GetXMLNodeByContent(string xmlcontent, string nodePath, string defaultval = "")
        {
            try
            {
                xmlDoc.LoadXml(xmlcontent);
                //XmlNodeList nodelist = xmlDoc.SelectNodes("/xml");
                XmlNode xmlNode = xmlDoc.SelectSingleNode(nodePath);
                if (xmlNode != null)
                    return xmlNode.InnerText.Trim();
                else
                    return defaultval;
            }
            catch
            {
                return null;
            }
        }
        #endregion

        #region 获取XML节点值
        /// <summary>
        /// 获取XML节点值
        /// </summary>
        /// <param name="xmlPath">XML文件路径(虚拟路径)</param>
        /// <param name="nodePath">从根节点开始到要获取属性值的节点路径,如/Root/NodeName</param>
        /// <returns></returns>
        public static string GetXmlNodeValue(this string xmlPath, string nodePath)
        {
            XmlNode xmlNode = GetXMLNode(xmlPath,nodePath);
            if (xmlNode != null)
                return xmlNode.InnerText.Trim();
            else
                return string.Empty;
        }
        /// <summary>
        /// 获取XML节点值
        /// </summary>
        /// <param name="xmlPath">XML文件路径(虚拟路径)</param>
        /// <param name="nodePath">从根节点开始到要获取属性值的节点路径,如/Root/NodeName</param>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public static string GetXmlNodeValue(this string xmlPath, string nodePath, string defaultValue)
        {
            XmlNode xmlNode = GetXMLNode(xmlPath, nodePath);
            if (xmlNode != null)
                return xmlNode.InnerText.Trim();
            else
                return defaultValue;
        }
        #endregion

        #region 设置XML节点值
        /// <summary>
        /// 设置XML节点值
        /// </summary>
        /// <param name="xmlPath">XML文件路径(虚拟路径)</param>
        /// <param name="nodePath">从根节点开始到要获取属性值的节点路径,如/Root/NodeName</param>
        /// <param name="nodeValue">节点值</param>
        public static void SetXmlNodeValue(this string xmlPath, string nodePath, string nodeValue)
        {
            XmlNode xmlNode = GetXMLNode(xmlPath, nodePath);
            if (xmlNode != null)
            {
                xmlNode.InnerText = nodeValue;
                xmlDoc.Save(System.Web.HttpContext.Current.Server.MapPath(xmlPath));
            }
        }
        #endregion

        #region 通用将XML转换成实体
        /// <summary>
        /// 通用将XML转换成实体
        /// </summary>
        /// <param name="xmlStr"></param>
        /// <returns></returns>
        public static List<object> GetObjectList(string xmlStr, XmlDocument xml, Type t, string nodeHeader)
        {
            List<object> olist = new List<object>();
            object obj = Activator.CreateInstance(t, null);//创建指定类型实例
            PropertyInfo[] fields = obj.GetType().GetProperties();//获取指定对象的所有公共属性
            XmlNodeList xlist = xml.GetElementsByTagName(nodeHeader);//获取Item节点列表
            foreach (XmlNode xn in xlist)//遍历Item节点下的子节点
            {
                object u = Activator.CreateInstance(t, null);//创建指定类型实例
                foreach (PropertyInfo p in fields)
                {
                    for (int i = 0; i < xn.ChildNodes.Count; )
                    {
                        if (xn.ChildNodes[i].Name.ToLower() == p.Name.ToLower())
                        {
                            p.SetValue(u, Convert.ChangeType(xn.ChildNodes[i].InnerText, p.PropertyType), null);//给创建的实例属性赋值
                        }
                        i++;
                    }
                }
                olist.Add(u);
            }
            return olist;
        }
        /// <summary>
        /// 通用将XML转换成实体
        /// </summary>
        /// <param name="xmlStr"></param>
        /// <returns></returns>
        public static object GetObject(string xmlStr,Type t, string nodeHeader)
        {
            object obj = Activator.CreateInstance(t, null);//创建指定类型实例
            PropertyInfo[] fields = obj.GetType().GetProperties();//获取指定对象的所有公共属性
            XmlDocument xml = new XmlDocument();
            xml.LoadXml(xmlStr);//加载xml
            XmlNodeList xlist = xml.GetElementsByTagName(nodeHeader);//获取Item节点列表

            object u = Activator.CreateInstance(t, null);//创建指定类型实例
            foreach (PropertyInfo p in fields)
            {
                for (int i = 0; i < xlist[0].ChildNodes.Count; )
                {
                    if (xlist[0].ChildNodes[i].Name == p.Name)
                    {
                        p.SetValue(u, Convert.ChangeType(xlist[0].ChildNodes[i].InnerText, p.PropertyType), null);//给创建的实例属性赋值
                    }
                    i++;
                }
            }
            return u;
        }
        #endregion

        #region C#如何将XmlDocument转化为string函数
        /// <summary>  
        /// 将XmlDocument转化为string  
        /// </summary>  
        /// <param name="xmlDoc"></param>  
        /// <returns></returns>  
        public static string ConvertXmlToString(XmlDocument xmlDoc)
        {
            MemoryStream stream = new MemoryStream();
            XmlTextWriter writer = new XmlTextWriter(stream, null);
            writer.Formatting = Formatting.Indented;
            xmlDoc.Save(writer);
            StreamReader sr = new StreamReader(stream, System.Text.Encoding.UTF8);
            stream.Position = 0;
            string xmlString = sr.ReadToEnd();
            sr.Close();
            stream.Close();
            return xmlString;
        }
        #endregion

        #region 将数据作为XML数据发送
        /// <summary>
        /// 将数据作为XML数据发送
        /// </summary>
        /// <param name="url"></param>
        /// <param name="xml"></param>
        public static void PostXml(string url, string xml)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(xml);
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "POST";
            request.ContentLength = bytes.Length;
            request.ContentType = "text/xml";
            using (Stream requestStream = request.GetRequestStream())
            {
                requestStream.Write(bytes, 0, bytes.Length);
            }

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            if (response.StatusCode != HttpStatusCode.OK)
            {
                string message = String.Format("POST failed. Received HTTP {0}",
                response.StatusCode);
                throw new ApplicationException(message);
            }
            ////ASP.NET中Request.InputStream使用 
            ////接收端通过Request.InputStream读取:
            //byte[] byts = new byte[Request.InputStream.Length];
            //Request.InputStream.Read(byts,0,byts.Length);
            //string req = System.Text.Encoding.Default.GetString(byts);
            //var req = Server.UrlDecode(req);

            ////对于完整的XML数据,可以:
            //System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
            //xmlDoc.Load(Request.InputStream);
        }
        #endregion

        #region C#获取远程xml文件
        /// <summary>
        /// 加载远程XML文档
        /// </summary>
        /// <param name="URL"></param>
        /// <returns></returns>
        public static XmlDocument ProcessItem(string URL)
        {
            //使用rssURL的值建立了一个WebRequest项              
            WebRequest myRequest = WebRequest.Create(URL);
            //WebRequest请求的响应将会被放到一个WebResponse对象myResponse里,然后这个WebResponse对象被用来建立一个流来取出XML的值
            WebResponse myResponse = myRequest.GetResponse();
            Stream stream = myResponse.GetResponseStream();
            //使用一个XmlDocument对象rssDoc来存储流中的XML内容。XmlDocument对象用来调入XML的内容              
            XmlDocument doc = new XmlDocument();
            doc.Load(stream);

            ////读取本地xml
            //XmlDocument xmlDoc = new XmlDocument();
            //XmlReaderSettings settings = new XmlReaderSettings();
            //settings.IgnoreComments = true;//忽略文档里面的注释
            //XmlReader reader = XmlReader.Create(@"..\..\text.xml", settings);
            //xmlDoc.Load(reader);
            //reader.Close();
            return doc;
        }
        #endregion

    }
}
